<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>147-动画-链式动画.html</title>
	<style>
		*{
			margin: 0;
			padding: 0;
		}
		div{
			height: 100px;
			width: 100px;
			background-color: skyblue;
			opacity: 0.5;
		}
	</style>
</head>
<body>
	<div id="div1">变宽</div>
	<div id="div2">变高</div>
	<div id="div3">变色</div>
</body>
<script>
	var oDiv1 = document.getElementById('div1');
	var oDiv2 = document.getElementById('div2');
	var oDiv3 = document.getElementById('div3');
	/*
	@param	{object} obj 		[DOM节点对象]
	@param	{string} attr		[属性名称]
	@param 	{number} target		[目标值]
	@param	{boolean} isLinear	[是否是匀速动画]
	@param	{function} fnEnd	[动画结束时执行的函数]
	*/
	function animation(obj,attr,target,isLinear,fnEnd){
		//设置默认是匀速动画
		if(isLinear == undefined){
			isLinear = true;
		}
		//防止多次操作开启多个定时器
		clearInterval(obj.timer);
		//速度/步长
		var iSpeed = 0;

		obj.timer = setInterval(function(){
			//isStopCurrent代表是否终止当前动画,由于在循环定时器中,所以每次执行都会变为false,代表不终止当前动画
			var isStopCurrent = false;
			//获取当前最新的值
			var current = parseFloat(getComputedStyle(obj,false)[attr]);
			//opacity属性的处理
			if(attr == 'opacity'){
				//1.乘以100是为了计算
				//2.四舍五入是为了处理小数
				current = Math.round(current * 100);
			}
			//匀速动画的处理
			if(isLinear){
				//确定匀速动画的速度
				if(current > target){
					iSpeed = -10;
				}else{
					iSpeed = 10;
				}
				//匀速动画终止条件
				if(Math.abs(target - current) < Math.abs(iSpeed)){
					//匀速动画终止后的处理:如果最后一次动画不够一个速度的话,直接到达目标值
					if(attr == 'opacity'){
						obj.style.opacity = target / 100;
					}else{
						obj.style[attr] = target + 'px';
					}
					//代表终止当前的动画
					isStopCurrent = true;
				}
			//减速动画的处理
			}else{
				//确定减速动画的速度
				iSpeed = (target - current) / 10;
				iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
				//减速动画的终止条件
				if(!iSpeed){
					//代表终止当前的动画
					isStopCurrent = true;
				}
			}
			//如果终止当前的动画,清除定时器
			if(isStopCurrent){
				clearInterval(obj.timer);
				//动画执行完毕后的执行函数
				/*
				if(typeof fnEnd == 'function'){
					fnEnd();
				}
				*/
				typeof fnEnd == 'function' && fnEnd();
			//如果不终止当前的动画,继续	
			}else{
				if(attr == 'opacity'){
					obj.style.opacity = (current + iSpeed) / 100;
				}else{
					obj.style[attr] = current + iSpeed + 'px'; 
					}		
				}	
		},30)
	}
	oDiv1.onmouseover = function(){
		animation(oDiv1,"width",400,true,function(){
			animation(oDiv1,"height",400,true,function(){
				animation(oDiv1,"opacity",100);
			});
		});
	}
	oDiv1.onmouseout = function(){
		animation(oDiv1,"opacity",50,true,function(){
			animation(oDiv1,"height",100,true,function(){
				animation(oDiv1,'width',100);
			});
		});
	}
	oDiv2.onmouseover = function(){
		animation(oDiv2,"height",400);
	}
	oDiv3.onmouseover = function(){
		animation(oDiv3,"opacity",100);
	}
</script>
</html>